package com.sita.redsun.connector.session;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SunSession {

    private Logger logger = LoggerFactory.getLogger(SunSession.class);

    private ChannelHandlerContext ctx;

    private Map<String, Object> map = new HashMap<String, Object>();

    private String host;
    private int port = 0;

    public SunSession(ChannelHandlerContext ctx) {
        this.ctx = ctx;

        InetSocketAddress isa = (InetSocketAddress)this.ctx.channel().remoteAddress();
        this.host = isa.getAddress().getHostAddress();
        this.port = isa.getPort();
    }

    public synchronized void set(String key, Object value) {
        map.put(key, value);
    }

    @SuppressWarnings("unchecked")
    public synchronized <T> T get(String key) {
        return (T) map.get(key);
    }

    public void setLastActiveTimeToNow() {
        set(Key.LAST_ACTIVE_TIME, System.currentTimeMillis());
    }

    public long getLastActiveTime() {
        return get(Key.LAST_ACTIVE_TIME);
    }

    public void setSessionUniqueId(String identifier) {
        set(Key.SESSION_UNIQUE_ID, identifier);
    }

    public String getSessionUniqueId() {
        return get(Key.SESSION_UNIQUE_ID);
    }

    public boolean isValid() {
        return getSessionUniqueId() != null ? true : false;
    }

    public synchronized void write(Object pkg) {
        ctx.writeAndFlush(pkg);
        logger.debug("CHANNEL_SEND " + pkg);
    }

    public synchronized void writeAndClose(Object pkg) {
        ChannelFuture future = ctx.writeAndFlush(pkg);
        future.addListener(ChannelFutureListener.CLOSE);
    }

    public String getHost() {
        return host;
    }

    public SunSession setHost(String host) {
        this.host = host;
        return this;
    }

    public int getPort() {
        return port;
    }

    public SunSession setPort(int port) {
        this.port = port;
        return this;
    }

    public synchronized void close() {

//        if (ctx != null && ctx.channel() != null
//                && (ctx.channel().isOpen() || ctx.channel().isActive())) {
        try {
            ChannelFuture future = ctx.close();
            setHost(null);
            setPort(0);
            future.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (future.isSuccess()) {
                        logger.debug("Session closed: CHANNEL_CLOSED ");
                    }
                }
            });
        } catch (Exception e) {
            logger.error("这是错误信息", e);
        }
//        }
    }

    private static class Key {
        private final static String LAST_ACTIVE_TIME = "last_active_time";
        private final static String SESSION_UNIQUE_ID = "session_unique_id";
    }
}
